home *** CD-ROM | disk | FTP | other *** search
- /*
- ARTemis (Graphic Editor for FM-TOWNS) (c) MATSUUCHI Ryosuke 1992,1993
-
- dispman.c Display Manager(表示管理部; 略称DM)
- */
-
- #include <stdio.h>
- #include <msdos.cf>
- #include <malloc.h>
- #include "ge.h"
- #include "imageman.h"
- #include "arealist.h"
-
- static int menuplt[16];
- static Arealist *menu1box;
- static Arealist *menu2box;
- #define HIGH16LOW32K 0
- #define HIGH32K 1
- static int scrtype; // HIGH16LOW32K / HIGH32K
- static int zoomrate;
- static int dispx,dispy;
- static int _dispxlen,_dispylen; // 表示されている範囲
- static int vx,vy; // VRAM 上に存在するimageの全体でのoffset
- static bool _lat1disp,_lat2disp;
- static int lat2xstep,lat2ystep;
- static int lat2xofs=0,lat2yofs=0;
- static bool maskdisp = NO;
-
- typedef struct {
- int x,y,xlen,ylen; // その時点の zoomrate での範囲
- char *gbuf1; // imagebuf の画像の保存用
- char *gbuf2; // menu2 レイヤの画像の保存用(スクロール時)
- } Menu2box;
-
- /*
- ★関数一覧
-
- DMnew DM の初期化
- DMdelete DM の終了
-
- DMgetifonepage レイヤ構成が1ページ上かどうかを得る
- DMgetxsize menu1レイヤの横幅
- DMgetysize menu1レイヤの縦幅
- DMgetmenuplt menu1レイヤにおけるパレット設定を得る
- DMdispcsr menu1レイヤに重ねてカーソルを表示
- DMerasecsr menu1レイヤ上のカーソルを消去
- DMchangecsrtype カーソルの種別の変更
-
- DMmenu1_addbox menu1レイヤに新たに矩形領域を設定する
- DMmenu1_deletebox menu1レイヤの矩形領域を削除する
- DMmenu2_addbox menu2レイヤに新たに矩形領域を設定する
- DMmenu2_deletebox menu2レイヤの矩形領域を削除する
-
- DMimage_setdispxy 編集画像のどこをimageレイヤに表示するか
- DMimage_limitdispxy ある座標の組を、dispx,dispy の設定限界内に制限
- する
- DMimage_refresh imageレイヤの内容を(編集画像に従って)更新する
- DMimage_setzoomrate imageレイヤの拡大率はなん倍か
- DMimage_getzoomrate 現在設定されている拡大率を得る
- DMimage_setlatticeswitch imageレイヤに重ねる格子を表示する・しない
- DMimage_setmaskdisp マスク部分を反転表示する・しない
- DMimage_getxbytes imageレイヤの1ラインのバイト数を得る
- DMimage_pset imageレイヤに点を打つ
- DMimage_line imageレイヤに直線を描く
- DMimage_hline imageレイヤに水平直線を描く
- DMimage_vline imageレイヤに垂直直線を描く
- DMimage_boxline imageレイヤに矩形(枠)を描く
- DMimage_boxfill imageレイヤに矩形フィルする
- */
-
- /*--------------------------------------------------------*/
- /* 領域分割の補助ルーチン */
- /*--------------------------------------------------------*/
-
- #define INTMIN (-100000)
- #define INTMAX ( 100000)
-
- static int andarea(Area *a1, Area *a2, Area *outarea)
- // Area a1,a2 の積の領域を outarea に代入
- // 返値: 積がφでなければ 1, φなら 0
- {
- outarea->x1 = _max(a1->x1, a2->x1);
- outarea->y1 = _max(a1->y1, a2->y1);
- outarea->x2 = _min(a1->x2, a2->x2);
- outarea->y2 = _min(a1->y2, a2->y2);
- if (outarea->x1 <= outarea->x2 && outarea->y1 <= outarea->y2)
- return 1;
- else
- return 0;
- }
-
- static void splitarea(Area *obj, Area *sbj, Arealist *outal)
- // obj を sbj で 0~4個の Area に分割し、それを outal に追加
- {
- Area a,a2;
- // sbj の上の領域
- a.x1=INTMIN, a.y1=INTMIN, a.x2=INTMAX, a.y2=sbj->y1-1;
- if (andarea(&a, obj, &a2))
- ALaddarea(outal, &a2);
- // sbj の左の領域
- a.x1=INTMIN, a.y1=sbj->y1, a.x2=sbj->x1-1, a.y2=sbj->y2;
- if (andarea(&a, obj, &a2))
- ALaddarea(outal, &a2);
- // sbj の右の領域
- a.x1=sbj->x2+1, a.y1=sbj->y1, a.x2=INTMAX, a.y2=sbj->y2;
- if (andarea(&a, obj, &a2))
- ALaddarea(outal, &a2);
- // sbj の下の領域
- a.x1=INTMIN, a.y1=sbj->y2+1, a.x2=INTMAX, a.y2=INTMAX;
- if (andarea(&a, obj, &a2))
- ALaddarea(outal, &a2);
- }
-
- static Arealist *makearealist() // menu1box に従い、画面を分割する
- {
- Arealist *al;
- Area a,*q;
- if ((al = ALnew()) == NULL)
- return NULL;
- a.x1=a.y1=0, a.x2=(scrtype==HIGH32K?511:639), a.y2=479;
- ALaddarea(al,&a);
- for (q=ALgetfirstarea(menu1box); q!=NULL; q=ALgetnextarea(menu1box))
- {
- Arealist *al2; Area *p;
- if ((al2 = ALnew()) == NULL)
- return NULL;
- for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
- splitarea(p, q, al2);
- ALdelete(al);
- al = al2;
- }
- return al;
- }
-
- /*--------------------------------------------------------*/
- /* 格子表示の補助ルーチン */
- /*--------------------------------------------------------*/
-
- static void _drawlattice(Area *area, bool lat1, int col1, bool lat2, int col2)
- {
- int t,x,xi,y,yi;
- if (zoomrate==1)
- return;
- if (zoomrate == 2)
- lat1 = NO;
- // 小格子の表示
- if (lat1)
- {
- for (t=area->x1+zoomrate-1, x=t-t%zoomrate+zoomrate-1, xi=t/zoomrate;
- x <= area->x2; x+=zoomrate, xi++)
- gvline(x,area->y1,area->y2,col1, DrawNORMAL);
- for (t=area->y1+zoomrate-1, y=t-t%zoomrate+zoomrate-1, yi=t/zoomrate;
- y <= area->y2; y+=zoomrate, yi++)
- ghline(area->x1,area->x2,y,col1,DrawNORMAL);
- }
- // 大格子の表示
- if (lat2)
- {
- for (t=area->x1+zoomrate-1, x=t-t%zoomrate+zoomrate-1, xi=t/zoomrate;
- x <= area->x2; x+=zoomrate, xi++)
- {
- if (((dispx+xi)-lat2xofs+1)%lat2xstep==0)
- gvline(x,area->y1,area->y2,col2, DrawNORMAL);
- }
- for (t=area->y1+zoomrate-1, y=t-t%zoomrate+zoomrate-1, yi=t/zoomrate;
- y <= area->y2; y+=zoomrate, yi++)
- {
- if (((dispy+yi)-lat2yofs+1)%lat2ystep==0)
- ghline(area->x1,area->x2,y,col2,DrawNORMAL);
- }
- }
- }
-
- static void dispalllattice()
- {
- Arealist *al; Area *p;
- if ((al = makearealist()) == NULL)
- return;
- for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
- _drawlattice(p,_lat1disp,menuplt[Black],_lat2disp,menuplt[LatticeColor]);
- ALdelete(al);
- }
-
- static void erasealllattice()
- {
- Arealist *al; Area *p;
- if (zoomrate == 1 || scrtype == HIGH32K || (al = makearealist()) == NULL)
- return;
- for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
- {
- gboxfill(p->x1,p->y1,p->x2,p->y2,0,DrawNORMAL);
- // _drawlattice(p,_lat1disp,0,_lat2disp,0);
- }
- ALdelete(al);
- }
-
- static void displattice2()
- {
- if (!_lat2disp)
- return;
- Arealist *al; Area *p;
- if ((al = makearealist()) == NULL)
- return;
- for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
- _drawlattice(p,NO,0,YES,menuplt[LatticeColor]);
- ALdelete(al);
- }
-
- static void eraselattice2()
- {
- Arealist *al; Area *p;
- if ((al = makearealist()) == NULL)
- return;
- for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
- _drawlattice(p,NO,0,YES,((_lat1disp && zoomrate > 2) ? menuplt[Black] : 0));
- ALdelete(al);
- }
-
- /*--------------------------------------------------------*/
- /* 画面モード設定の補助ルーチン */
- /*--------------------------------------------------------*/
-
- static void setscreen()
- // scrtype に従って画面モードを設定、パレットの初期化も行う
- {
- if (scrtype == HIGH16LOW32K)
- {
- gwrtpage(0);
- gscreen(3);
- gwrtpage(1);
- gscreen(10);
- gdsploc(0,0);
- gscrzoom(zoomrate,zoomrate);
- gdsparea(640/zoomrate,480/zoomrate);
- gwrtpage(0);
- // パレット設定
- grp_setplt(0, 0x000000);
- grp_setplt(Black, 0x000000);
- grp_setplt(Gray1, 0x202020);
- grp_setplt(Gray2, 0x303030);
- grp_setplt(Gray3, 0x505050);
- grp_setplt(Gray4, 0x707070);
- grp_setplt(Gray5, 0x808080);
- grp_setplt(Gray6, 0xa0a0a0);
- grp_setplt(Gray7, 0xc0c0c0);
- grp_setplt(Gray8, 0xd0d0d0);
- grp_setplt(White, 0xf0f0f0);
- grp_setplt(Yellow, 0xf0f000);
- grp_setplt(COL_menuShade, 0x404050);
- grp_setplt(COL_menu, 0x9090b0);
- grp_setplt(COL_menuLight, 0xe0e0f0);
- grp_setplt(COL_menu2, 0xb0b0c0);
- }
- else if (scrtype == HIGH32K)
- {
- gwrtpage(0);
- gscreen(17);
- gdsploc(0,0);
- gscrzoom(1,1);
- gdsparea(512,480);
- grboxfill(0,0,512,480,0,DrawNORMAL);
- }
- }
-
- /*--------------------------------------------------------*/
- /* menuplt の設定 */
- /*--------------------------------------------------------*/
-
- static void setmenuplt()
- {
- int i;
- if (scrtype == HIGH16LOW32K)
- {
- for (i=0; i<16; i++)
- menuplt[i] = i;
- }
- else if (scrtype == HIGH32K)
- {
- for (i=0; i<16; i++)
- {
- switch (i)
- {
- case White: menuplt[i] = 32767; break;
- case Black: menuplt[i] = 0; break;
- #define G(n) ((n)*1024+(n)*32+(n))
- case Gray1: menuplt[i] = G(3); break;
- case Gray2: menuplt[i] = G(7); break;
- case Gray3: menuplt[i] = G(10); break;
- case Gray4: menuplt[i] = G(14); break;
- case Gray5: menuplt[i] = G(17); break;
- case Gray6: menuplt[i] = G(21); break;
- case Gray7: menuplt[i] = G(24); break;
- case Gray8: menuplt[i] = G(28); break;
- #undef G
- case Transparent: menuplt[i] = 0x8000; break;
- case Yellow: menuplt[i] = 31*1024+31*32+ 0; break;
- case COL_menu: menuplt[i] = 19*1024+19*32+22; break;
- case COL_menuLight: menuplt[i] = 28*1024+28*32+31; break;
- case COL_menuShade: menuplt[i] = 8*1024+8*32+10; break;
- case COL_menu2: menuplt[i] = 22*1024+22*32+24; break;
- default: menuplt[i] = 31; break;
- }
- }
- }
- }
-
- /*--------------------------------------------------------*/
- /* Display Manager の初期化/終了 */
- /*--------------------------------------------------------*/
-
- int DMnew(int reso) // DM の初期化
- // reso: 0 = 画面を16色高解像度ページ+32K色低解像度ページの構成で初期化
- // 1 = 画面を32K色高解像度ページのみの構成で初期化
- // 返値 0=成功
- {
- int i;
- if ((menu1box = ALnew()) == NULL)
- return -1;
- if ((menu2box = ALnew()) == NULL)
- return -1;
- scrtype = (reso==0 ? HIGH16LOW32K : HIGH32K);
- dispx = dispy = 0;
- vx = vy = 0;
- _lat1disp = _lat2disp = NO;
- lat2xstep = lat2ystep = 16;
- lat2xofs = lat2yofs = 0;
- if (scrtype == HIGH16LOW32K)
- zoomrate=2, _dispxlen=640/zoomrate, _dispylen=480/zoomrate;
- else if (scrtype == HIGH32K)
- zoomrate=1, _dispxlen=512, _dispylen=480;
- setmenuplt();
- // 画面モードの設定
- ginit();
- EGB_work = _egbwork;
- setscreen();
- }
-
- void DMdelete(void) // DM の終了
- {
- if (scrtype == HIGH16LOW32K)
- {
- gwrtpage(0);
- grboxfill(0,0,640,480,0,DrawNORMAL);
- gwrtpage(1);
- grboxfill(0,0,512,256,0,DrawNORMAL);
- gwrtpage(0);
- }
- else
- {
- gwrtpage(0);
- grboxfill(0,0,512,480,0,DrawNORMAL);
- }
- }
-
- /*--------------------------------------------------------*/
- /* Display Manager の各種パラメータの取得 */
- /*--------------------------------------------------------*/
-
- int DMgetifonepage(void) // レイヤ構成が1ページ上かどうかを得る
- // 返値: 0=1ページ上ではない 1=1ページ上
- {
- return (scrtype == HIGH16LOW32K ? 0 : 1);
- }
-
- int DMgetxsize(void) // menu1レイヤの横幅を得る
- {
- return (scrtype == HIGH32K ? 512 : 640);
- }
-
- int DMgetysize(void) // menu1レイヤの縦幅を得る
- {
- return 480;
- }
-
- void DMimage_getdispxy(int *x,int *y)
- {
- *x = dispx;
- *y = dispy;
- }
-
- void DMimage_getdispxylen(int *xlen, int *ylen)
- {
- *xlen = _dispxlen;
- *ylen = _dispylen;
- }
-
- int DMgetpage1x(int x)
- {
- if (scrtype == HIGH16LOW32K)
- return (dispx-vx)+x/zoomrate;
- else if (scrtype == HIGH32K)
- return x;
- }
-
- int DMgetpage1y(int y)
- {
- if (scrtype == HIGH16LOW32K)
- return (dispy-vy)+y/zoomrate;
- else if (scrtype == HIGH32K)
- return y;
- }
-
- void DMimage_getvramxy(int *x, int *y)
- {
- *x = vx;
- *y = vy;
- }
-
- int DMgetmenuplt(int n) // menu1レイヤにおけるパレット設定を得る
- {
- return menuplt[n];
- }
-
- int DMimage_getzoomrate()
- {
- return zoomrate;
- }
-
- int DMimage_getxbytes()
- {
- return 1024;
- }
-
-
- static bool csrdisp = NO;
- static int csrx,csry;
-
- void DMerasecsr(void) // menu1レイヤ上のカーソルを消去
- {
- if (!csrdisp)
- return;
- csrdisp = NO;
- int col;
- col = (DMgetifonepage() ? White : csrcol);
- ghline(0,DMgetxsize()-1,csry,DMgetmenuplt(col),DrawXOR);
- gvline(csrx,0,DMgetysize()-1,DMgetmenuplt(col),DrawXOR);
- }
-
- void DMdispcsr(int x,int y) // menu1レイヤに重ねてカーソルを表示
- {
- if (csrdisp)
- DMerasecsr();
- if (0 <= x && x < DMgetxsize() && 0<=y && y<DMgetysize())
- {
- csrdisp = YES;
- csrx = x;
- csry = y;
- int col;
- col = (DMgetifonepage() ? White : csrcol);
- ghline(0,DMgetxsize()-1,y,DMgetmenuplt(col),DrawXOR);
- gvline(x,0,DMgetysize()-1,DMgetmenuplt(col),DrawXOR);
- }
- }
-
-
- void DMchangecsrtype(int type) // カーソルの種別の変更
- {
- }
-
- /*--------------------------------------------------------*/
- /* menu1, menu2 レイヤに領域を追加/削除する */
- /*--------------------------------------------------------*/
-
- int DMmenu1_addbox(int x,int y,int xlen,int ylen)
- // menu1レイヤに新たに矩形領域を設定する
- {
- Area a,*ap; bool sw2nd;
- a.x1=x, a.y1=y, a.x2=x+xlen-1, a.y2=y+ylen-1;
- sw2nd = (ALgetfirstarea(menu1box) == NULL ? NO : YES); // 2番目以降?
- if ((ap = ALaddarea(menu1box, &a)) == NULL)
- return -1;
- int bufsize; char *gbuf;
- if (scrtype == HIGH16LOW32K)
- bufsize = (((xlen+7)/8)*8)*ylen/2;
- else if (scrtype == HIGH32K)
- bufsize = xlen*ylen*2;
- if (sw2nd)
- {
- if ((gbuf = malloc(bufsize)) == NULL) {
- ALdeletearea(menu1box);
- return -1;
- }
- ALarea_setdata(ap,gbuf);
- gwrtpage(0);
- grgetblk(gbuf,x,y,xlen,ylen);
- }
- else
- ALarea_setdata(ap,NULL);
- return 0;
- }
-
- int DMmenu1_deletebox(void) // menu1レイヤの矩形領域を削除する
- // (最後に設定した領域を削除する)
- {
- Area *ap; char *gbuf;
- if ((ap = ALgetfirstarea(menu1box)) != NULL)
- {
- if ((gbuf = ALarea_getdata(ap)) != NULL)
- {
- grputblk(ap->x1, ap->y1, ap->x2-ap->x1+1, ap->y2-ap->y1+1,
- gbuf,DrawNORMAL);
- free(gbuf);
- }
- else
- gboxfill(ap->x1,ap->y1,ap->x2,ap->y2,0,DrawNORMAL);
- ALdeletearea(menu1box);
- }
- if (scrtype == HIGH32K)
- DMimage_refresh();
- erasealllattice();
- dispalllattice();
- return 0;
- }
-
- int DMmenu2_addbox(int x,int y,int xlen,int ylen)
- // menu2レイヤに新たに矩形領域を設定する
- {
- Area a,*ap;
- a.x1=x, a.y1=y, a.x2=x+xlen-1, a.y2=y+ylen-1;
- if ((ap=ALaddarea(menu2box, &a)) == NULL)
- return -1;
- if (scrtype == HIGH16LOW32K)
- {
- Menu2box b,*bp;
- b.x = x / zoomrate;
- b.y = y / zoomrate;
- b.xlen = (xlen+zoomrate-1) / zoomrate;
- b.ylen = (ylen+zoomrate-1) / zoomrate;
- if ((bp = (Menu2box*)malloc(sizeof(Menu2box)+b.xlen*b.ylen*4)) == NULL)
- {
- ALdeletearea(menu2box);
- return -1;
- }
- *bp = b;
- bp->gbuf1 = (char*)bp + sizeof(Menu2box);
- bp->gbuf2 = (char*)bp + sizeof(Menu2box) + b.xlen*b.ylen*2;
- gwrtpage(1);
- grgetblk(bp->gbuf1,dispx-vx+b.x,dispy-vy+b.y,b.xlen,b.ylen);
- gwrtpage(0);
- ALarea_setdata(ap,bp);
- }
- return 0;
- }
-
- int DMmenu2_deletebox(void) // menu2レイヤの矩形領域を削除する
- {
- if (scrtype == HIGH16LOW32K)
- {
- Area *ap;
- if ((ap = ALgetfirstarea(menu2box)) != NULL)
- {
- Menu2box *bp;
- bp = (Menu2box *)ALarea_getdata(ap);
- gwrtpage(1);
- grputblk(dispx-vx+bp->x,dispy-vy+bp->y,
- bp->xlen,bp->ylen,bp->gbuf1, DrawNORMAL);
- gwrtpage(0);
- free(bp);
- }
- }
- ALdeletearea(menu2box);
- return 0;
- }
-
-
- /*--------------------------------------------------------*/
- /* image レイヤの表示位置の変更 */
- /*--------------------------------------------------------*/
-
- void DMimage_limitdispxy(int x, int y, int *newx, int *newy)
- {
- *newx = x, *newy = y;
- if (x < 0)
- *newx = 0;
- else if (x + _dispxlen > EIMgetxsize())
- *newx = EIMgetxsize() - _dispxlen;
- if (y < 0)
- *newy = 0;
- else if (y + _dispylen > EIMgetysize())
- *newy = EIMgetysize() - _dispylen;
- }
-
- int DMimage_setdispxy(int x,int y) // 編集画像のどこをimageレイヤに表示するか
- // 結果的に x,y がどうなったかも返すべき?
- {
- Area *ap;
- if (x < 0)
- x = 0;
- else if (x+_dispxlen > EIMgetxsize())
- x = EIMgetxsize() - _dispxlen;
- if (y < 0)
- y = 0;
- else if (y+_dispylen > EIMgetysize())
- y = EIMgetysize() - _dispylen;
- if (scrtype == HIGH16LOW32K)
- {
- /*
- 画面モード構成が16色高解像度+32K色低解像度の場合:
-
- 新たに表示したい領域が、すでにVRAM上に存在する範囲ならば、
- ハード的に表示範囲を変更するだけ。
- ここで、「新たに表示したい領域」とは、編集画像上のある矩形領域
- であり、その基準座標は(x,y)、大きさは
- (DMgetxsize()/zoomrate, DMgetysize()/zoomrate) という領域である。
-
- この領域が、まだ VRAM上に存在しない領域を含んでいる場合、
- 編集画像バッファよりデータを転送する。
- (x,y)-VRAM上に存在しない領域を表示したいという場合は、
- */
- eraselattice2();
- // menu2box の内容を復帰
- if ((ap = ALgetfirstarea(menu2box)) != NULL)
- {
- gwrtpage(1);
- for ( ; ap!=NULL; ap=ALgetnextarea(menu2box))
- {
- Menu2box *bp;
- bp = (Menu2box*)ALarea_getdata(ap);
- grgetblk(bp->gbuf2,
- dispx-vx+bp->x,dispy-vy+bp->y,bp->xlen,bp->ylen);
- grputblk(dispx-vx+bp->x,dispy-vy+bp->y,bp->xlen,bp->ylen,
- bp->gbuf1,DrawNORMAL);
- }
- gwrtpage(0);
- }
- bool vc = NO; // vx,vyを変更したかどうか
- if (x < vx)
- vx = _max(0, x+_dispxlen-512), vc=YES;
- else if (vx+512 < x+_dispxlen)
- vx = _min(EIMgetxsize()-512, x), vc=YES;
- if (y < vy)
- vy = _max(0, y+_dispylen-256), vc=YES;
- else if (vy+256 < y+_dispylen)
- vy = _min(EIMgetysize()-256, y), vc=YES;
- if (vc)
- xymemcpy(0x104,0x40000, getds(),(int)EIMadrs(vx,vy),
- 512*2, 256, DMimage_getxbytes(), EIMgetxbytes());
- dispx = x, dispy = y;
- gwrtpage(1);
- gdsploc(dispx-vx,dispy-vy);
- gwrtpage(0);
- // menu2box の内容を退避
- if ((ap = ALgetfirstarea(menu2box)) != NULL)
- {
- gwrtpage(1);
- for ( ; ap!=NULL; ap=ALgetnextarea(menu2box))
- {
- Menu2box *bp;
- bp = (Menu2box*)ALarea_getdata(ap);
- grgetblk(bp->gbuf1,
- dispx-vx+bp->x,dispy-vy+bp->y,bp->xlen,bp->ylen);
- grputblk(dispx-vx+bp->x,dispy-vy+bp->y,bp->xlen,bp->ylen,
- bp->gbuf2,DrawNORMAL);
- }
- gwrtpage(0);
- }
- displattice2();
- }
- else if (scrtype == HIGH32K)
- {
- dispx = x, dispy = y;
- if (zoomrate == 1)
- {
- Arealist *al; Area *p;
- if ((al = makearealist()) != NULL)
- {
- for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
- xymemcpy(0x10c,1024*p->y1+p->x1*2,
- getds(),(int)EIMadrs(dispx + p->x1,dispy + p->y1),
- (p->x2 - p->x1 + 1)*2, p->y2 - p->y1 + 1,
- DMimage_getxbytes(), EIMgetxbytes());
- ALdelete(al);
- }
- }
- }
- return 0;
- }
-
- /*--------------------------------------------------------*/
- /* image レイヤの内容の更新 */
- /*--------------------------------------------------------*/
-
- int DMimage_refresh(void) // imageレイヤの内容を(編集画像に従って)更新する
- {
- if (scrtype == HIGH16LOW32K)
- {
- xymemcpy(0x104,0x40000, getds(),(int)EIMadrs(vx,vy),
- 512*2, 256, DMimage_getxbytes(), EIMgetxbytes());
- }
- else if (scrtype == HIGH32K)
- {
- Arealist *al; Area *p;
- if ((al = makearealist()) != NULL)
- {
- for (p=ALgetfirstarea(al); p!=NULL; p=ALgetnextarea(al))
- xymemcpy(0x10c,1024*p->y1+p->x1*2,
- getds(),(int)EIMadrs(dispx + p->x1,dispy + p->y1),
- (p->x2 - p->x1 + 1)*2, p->y2 - p->y1 + 1,
- DMimage_getxbytes(), EIMgetxbytes());
- ALdelete(al);
- }
- }
- return 0;
- }
-
- /*--------------------------------------------------------*/
- /* image レイヤの拡大率の変更 */
- /*--------------------------------------------------------*/
-
- void DMimage_setzoomrate(int rate)
- {
- if (zoomrate == rate)
- ;
- else if (zoomrate == 1 && rate > 1)
- {
- zoomrate = rate;
- _dispxlen = 640/zoomrate, _dispylen = 480/zoomrate;
- vx = dispx - (512-_dispxlen)/2;
- vy = dispy - (256-_dispylen)/2;
- vx = _lim(vx, 0, EIMgetxsize()-512);
- vy = _lim(vy, 0, EIMgetysize()-256);
- scrtype = HIGH16LOW32K;
- setscreen();
- grboxfill(0,0,640,480,0,DrawNORMAL);
- xymemcpy(0x104,0x40000, getds(),(int)EIMadrs(vx,vy),
- 512*2, 256, DMimage_getxbytes(), EIMgetxbytes());
- gwrtpage(1);
- gscrzoom(zoomrate,zoomrate);
- gdsparea(320,240);
- gdsploc(dispx-vx,dispy-vy);
- gwrtpage(0);
- setmenuplt();
- dispalllattice();
- }
- else if (zoomrate > 1 && rate == 1)
- {
- zoomrate = rate;
- _dispxlen = 512, _dispylen = 480;
- dispx = _min(dispx, EIMgetxsize()-512);
- dispy = _min(dispy, EIMgetysize()-256);
- scrtype = HIGH32K;
- setscreen();
- xymemcpy(0x10c,0,
- getds(),(int)EIMadrs(dispx,dispy),
- _dispxlen*2, _dispylen,
- DMimage_getxbytes(), EIMgetxbytes());
- setmenuplt();
- dispalllattice();
- }
- else if (zoomrate > 1 && rate > 1)
- {
- zoomrate = rate;
- _dispxlen = 640/zoomrate, _dispylen = 480/zoomrate;
- dispx = _min(dispx, EIMgetxsize()-_dispxlen);
- dispy = _min(dispy, EIMgetysize()-_dispylen);
- bool vc = NO;
- if (dispx < vx)
- vx = _max(0, dispx+_dispxlen-512), vc=YES;
- else if (vx+512 < dispx+_dispxlen)
- vx = _min(EIMgetxsize()-512, dispx), vc=YES;
- if (dispy < vy)
- vy = _max(0, dispy+_dispylen-512), vc=YES;
- else if (vy+256 < dispy+_dispylen)
- vy = _min(EIMgetysize()-256, dispy), vc=YES;
- if (vc)
- xymemcpy(0x104,0x40000, getds(),(int)EIMadrs(vx,vy),
- 512*2, 256, DMimage_getxbytes(), EIMgetxbytes());
- gwrtpage(1);
- gdsploc(dispx-vx,dispy-vy);
- gscrzoom(zoomrate,zoomrate);
- gwrtpage(0);
- dispalllattice();
- }
- }
-
- /*--------------------------------------------------------*/
- /* image レイヤの格子の表示/非表示の切り換え */
- /*--------------------------------------------------------*/
-
- void DMimage_setlatticesize(int xlen,int ylen)
- {
- erasealllattice();
- lat2xstep = xlen;
- lat2ystep = ylen;
- dispalllattice();
- }
-
- void DMimage_setlatticeswitch(bool lat1, bool lat2)
- {
- erasealllattice();
- _lat1disp = lat1;
- _lat2disp = lat2;
- dispalllattice();
- }
-
- void DMimage_getlatticeswitch(bool *lat1, bool *lat2)
- {
- *lat1 = _lat1disp;
- *lat2 = _lat2disp;
- }
-
- void DMimage_getlatticesize(int *xsize,int *ysize)
- {
- *xsize = lat2xstep;
- *ysize = lat2ystep;
- }
-
- /*--------------------------------------------------------*/
- /* マスク領域の反転表示スイッチの切り換え */
- /*--------------------------------------------------------*/
-
- void DMimage_setmaskdisp(bool disp)
- {
- maskdisp = disp;
- DMimage_refresh();
- }
-
- /*--------------------------------------------------------*/
- /* image レイヤ内での座標を得る */
- /*--------------------------------------------------------*/
-
- int DMimage_getx(int x)
- // x: menu1レイヤでの座標
- {
- return dispx+x/zoomrate;
- }
-
- int DMimage_gety(int y)
- {
- return dispy+y/zoomrate;
- }
-
- /*--------------------------------------------------------*/
- /* image レイヤに対する描画コマンド */
- /*--------------------------------------------------------*/
-
- void DMimage_pset(int x,int y,int col,int op) // imageレイヤに点を打つ
- // 点を打つときには、menu1レイヤのbox[0]だけを避ける。
- {
- if (scrtype == HIGH16LOW32K)
- {
- x -= vx, y -= vy;
- if (0 <= x && x < 512 && 0 <= y && y < 256)
- {
- if (op == DrawXOR)
- MEMstoreword_xor(0x104,(char*)(0x40000+1024*y+x*2), col,1);
- else
- MEMstoreword(0x104,(char*)(0x40000+1024*y+x*2), col,1);
- // gwrtpage(1);
- // gpset(x,y,col,op);
- // gwrtpage(0);
- }
- }
- else if (scrtype == HIGH32K)
- {
- x -= dispx, y -= dispy;
- if (zoomrate == 1)
- {
- Area *ap;
- ap = ALgetfirstarea(menu1box);
- if (0 <= x && x < 512 && 0 <= y && y < 480)
- {
- if (ap == NULL)
- {
- if (op == DrawXOR)
- MEMstoreword_xor(0x10c,(char*)(1024*y+x*2), col,1);
- else
- MEMstoreword(0x10c,(char*)(1024*y+x*2), col,1);
- // gpset(x,y,col,op);
- }
- else if (x < ap->x1 || y < ap->y1 || ap->x2 < x || ap->y2 < y)
- {
- if (op == DrawXOR)
- MEMstoreword_xor(0x10c,(char*)(1024*y+x*2), col,1);
- else
- MEMstoreword(0x10c,(char*)(1024*y+x*2), col,1);
- // gpset(x,y,col,op);
- }
- }
- }
- }
- }
-
- void DMimage_line(int x1,int y1,int x2,int y2,int col,int op)
- // imageレイヤに直線を描く
- {
- int x,y,xr,yr,r;
- xr = _abs(x2-x1), yr = _abs(y2-y1);
- if (xr == 0 && yr == 0)
- DMimage_pset(x1,y1,col,op);
- else if (xr > yr)
- {
- r = (yr<<16) / xr;
- if (x2 < x1)
- { swap(x1,x2); swap(y1,y2); }
- if (y1 > y2)
- r = -r;
- for (x=x1,y=(y1<<16)+0x8000; x<=x2; x++,y+=r)
- DMimage_pset(x,(y>>16),col,op);
- }
- else
- {
- r = (xr << 16) / yr;
- if (y2 < y1)
- { swap(x1,x2); swap(y1,y2); }
- if (x1 > x2)
- r = -r;
- for (y=y1,x=(x1<<16)+0x8000; y<=y2; y++,x+=r)
- DMimage_pset((x>>16),y,col,op);
- }
- }
-
- void DMimage_hline(int x1,int x2,int y,int col,int op)
- // imageレイヤに水平直線を描く
- {
- if (scrtype == HIGH16LOW32K)
- {
- gwrtpage(1);
- x1 -= vx, x2 -= vx, y -= vy;
- if (x1>x2)
- swap(x1,x2);
- x1 = _max(0,x1);
- x2 = _min(512-1,x2);
- if (x1 <= x2 && 0<=y && y<256)
- ghline(x1,x2,y,col,op);
- gwrtpage(0);
- }
- else if (scrtype == HIGH32K)
- {
- x1 -= dispx, x2 -= dispx, y -= dispy;
- if (x1>x2)
- swap(x1,x2);
- x1 = _max(0,x1);
- x2 = _min(512-1,x2);
- if (x1 <= x2 && 0<=y && y<480)
- {
- if (zoomrate == 1)
- {
- bool box = YES;
- Area *ap = ALgetfirstarea(menu1box);
- if (ap == NULL)
- box = NO;
- else if (y < ap->y1 || ap->y2 < y)
- box = NO;
- if (box)
- {
- if (x1 < ap->x1)
- ghline(x1,_min(x2,ap->x1-1),y,col,op);
- if (ap->x2 < x2)
- ghline(_max(x1,ap->x2+1),x2,y,col,op);
- }
- else
- ghline(x1,x2,y,col,op);
- }
- }
- }
- }
-
- void DMimage_hline_map(int x1,int x2,int y,char *colmap)
- // colmap には、カラーコードが順に並んでいるものとする。
- // この関数は、その色の並びの水平直線を image レイヤに描く。
- {
- if (scrtype == HIGH16LOW32K)
- {
- gwrtpage(1);
- x1 -= vx, x2 -= vx, y -= vy;
- if (x1>x2)
- swap(x1,x2);
- int x10 = x1;
- x1 = _max(0,x1);
- x2 = _min(512-1,x2);
- colmap += (x1-x10)*2;
- if (x1 <= x2 && 0<=y && y<256)
- {
- xmemcpy(0x104,0x40000+1024*y+x1*2,getds(),(int)colmap,(x2-x1+1)*2);
- // ghline(x1,x2,y,col,op);
- }
- gwrtpage(0);
- }
- else if (scrtype == HIGH32K)
- {
- x1 -= dispx, x2 -= dispx, y -= dispy;
- if (x1>x2)
- swap(x1,x2);
- int x10 = x1;
- x1 = _max(0,x1);
- x2 = _min(512-1,x2);
- colmap += (x1-x10)*2;
- if (x1 <= x2 && 0<=y && y<480)
- {
- if (zoomrate == 1)
- {
- bool box = YES;
- Area *ap = ALgetfirstarea(menu1box);
- if (ap == NULL)
- box = NO;
- else if (y < ap->y1 || ap->y2 < y)
- box = NO;
- if (box)
- {
- if (x1 < ap->x1)
- {
- int right = _min(x2,ap->x1-1);
- xmemcpy(0x10c,1024*y+x1*2,getds(),(int)colmap,(right-x1+1)*2);
- // ghline(x1,_min(x2,ap->x1-1),y,col,op);
- }
- if (ap->x2 < x2)
- {
- int left = _max(x1,ap->x2+1);
- xmemcpy(0x10c,1024*y+left*2,getds(),(int)(colmap+(left-x1)*2),(x2-left+1)*2);
- // ghline(_max(x1,ap->x2+1),x2,y,col,op);
- }
- }
- else
- {
- xmemcpy(0x10c,1024*y+x1*2,getds(),(int)colmap,(x2-x1+1)*2);
- // ghline(x1,x2,y,col,op);
- }
- }
- }
- }
- }
-
- void DMimage_vline(int x,int y1,int y2,int col,int op)
- // imageレイヤに垂直直線を描く
- {
- if (scrtype == HIGH16LOW32K)
- {
- gwrtpage(1);
- x -= vx, y1 -= vy, y2 -= vy;
- if (y1>y2)
- swap(y1,y2);
- y1 = _max(0,y1);
- y2 = _min(256-1,y2);
- if (y1 <= y2 && 0<=x && x<512)
- gvline(x,y1,y2,col,op);
- gwrtpage(0);
- }
- else if (scrtype == HIGH32K)
- {
- x -= dispx, y1 -= dispy, y2 -= dispy;
- if (y1>y2)
- swap(y1,y2);
- y1 = _max(0,y1);
- y2 = _min(480-1,y2);
- if (y1 <= y2 && 0<=x && x<512)
- {
- if (zoomrate == 1)
- {
- bool box = YES;
- Area *ap = ALgetfirstarea(menu1box);
- if (ap == NULL)
- box = NO;
- else if (x < ap->x1 || ap->x2 < x)
- box = NO;
- if (box)
- {
- if (y1 < ap->y1)
- gvline(x,y1,_min(y2,ap->y1-1),col,op);
- if (ap->y2 < y2)
- gvline(x,_max(y1,ap->y2+1),y2,col,op);
- }
- else
- gvline(x,y1,y2,col,op);
- }
- }
- }
- }
-
- void DMimage_rboxline(int x,int y,int xlen,int ylen,int col, int op)
- // imageレイヤに矩形(枠)を描く
- {
- DMimage_hline(x,x+xlen-1,y,col,op);
- if (ylen >= 2)
- DMimage_hline(x,x+xlen-1,y+ylen-1,col,op);
- if (ylen >= 3)
- DMimage_vline(x,y+1,y+ylen-2,col,op),
- DMimage_vline(x+xlen-1,y+1,y+ylen-2,col,op);
- }
-
- void DMimage_boxfill(int x,int y,int xlen,int ylen,int col, int op)
- // imageレイヤに矩形フィルする
- {
- int iy;
- for (iy=0; iy<ylen; iy++)
- DMimage_hline(x,x+xlen-1,y+iy,col,op);
- }
-
- /*
- ARTemis の画面表示はすべてこのモジュールを通して行う。
- 32K色高解像度のときと 32K 低解像度のときの画面構成の違いを吸収するため、
- 以下の3つの仮想レイヤを想定し、ARTemis の画面表示はこれらのレイヤに対
- して行うようプログラミングする。
-
- menu1 レイヤ メニューを表示するためのレイヤ。
-
- このレイヤに対して行える操作は、「矩形領域の設定」
- と同じく「解除」の2通りだけである。
- 矩形領域というのはメニューを表示するための領域で、
- 「設定」された矩形領域については、他のレイヤを操作
- したときにも表示内容をそのままに保つのがDMの働き
- である。
-
- このレイヤにアクセスするのは「メニュー管理部」だけで
- ある。
- メニュー管理部(MM)は、メニューを表示する必要が生じ
- た場合、このmenu1レイヤとmenu2レイヤ上に矩形領域を
- 「借りて」、その領域内でメニュー処理を行う。メニュー
- を移動する際には、借りた矩形領域を「返して」別の座標
- の領域を借りる、という動作をMMは行う。
-
- DMは「設定された=MMが借りた」領域に対して、そこ
- にMMが表示する内容を「守る」はたらきをする。すなわ
- ち、imageレイヤにいろいろな操作(スクロールや格子表示
- のオン・オフなど)を加えても、menu1レイヤに表示されて
- いる内容はそのまま変化せず表示されているようにする。
-
- menu2 レイヤ メニューを表示するためのレイヤその2
-
- menu1 レイヤが32K色高解像度の画面モードのときには、こ
- の menu2 レイヤは全くいらない。
- しかし、menu1 レイヤが16色モードの場合、menu1 レイヤ
- には32K色パレットリストが表示できない。その場合、32K
- 色パレットリストはこの menu2 レイヤに用意する。
-
- このレイヤは、ハード構成に則して見ると、画面が16色高
- 解像+32K色低解像度の構成の時に、32K色のページに表示
- される。
-
- この menu2 レイヤに対し行える操作は、「矩形領域の設定」
- と同じく「解除」の2通りだけである。
- 「設定」できる矩形領域は、このレイヤ内に1つだけであ
- る。
-
- このレイヤにアクセスするのはMMだけである。MMは、
- 画面構成が上のような条件のときにメニューを表示する
- 必要が生じた場合、menu2 レイヤから矩形領域を「借り
- て」そこに、32Kを用いたメニュー表示を行う(もちろん、
- メニューが32K色表示を必要としない場合はMMは
- menu2 レイヤを使用しない)。
-
- DMは、image レイヤに対してスクロールや描画などの
- 操作が行われた場合にも、このmenu2レイヤの表示内容を
- 画面上で保存する働きをする。
-
- image レイヤ 編集画像と格子を表示するためのレイヤ
-
- 編集画像を表示する。16色+32K色の2ページ構成の場合
- には、32K色ページをハード的に拡大してARTemisの拡大
- 表示機能を実現する。32K色高解像度の1ページ構成の
- 場合には、編集画像をソフト的に拡大してARTemisの拡大
- 表示機能を実現する。
-
- ハード的に見ると、32K色高解像モード×1ページの場合
- はそのページのことである。16色高解像+32K色低解像の
- 場合は、格子を16色高解像のページに表示し、編集画像
- を 32K色低解像のページに表示する。
- */
-